////////////////////////////////////////////////////////
//@time:2013-03-23 13:35
//@author:lwd
//
//implement the basic function of queue
//
////////////////////////////////////////////////////////
#include <malloc.h>
#include "Queue.h"

Status initQueue(LinkQueue *Q)
{
	// create and init the queue Q
	Q->front = Q->rear = (QueuePtr)malloc( sizeof(QNode) );
	if( !Q->front ) 
	{
		return ERROR;
	}
	Q->front->next = NULL;
	
	return OK;
}

Status DestoryQueue(LinkQueue *Q)
{
	//destory the queue Q 
	while(Q->front){
		Q->rear = Q->front->next;
		free(Q->rear);
		Q->front = Q->rear;
	}
	
	return OK;
}

Status EnQueue(LinkQueue *Q, QElemType e)
{
	//insert a node into the queue Q
	QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
	if(!p)
	{
		return ERROR;
	}
	p->data = e;
	p->next = NULL;
	Q->rear->next = p;
	Q->rear = p;
	
	return OK;
}

Status DeQueue(LinkQueue *Q, QElemType *e)
{
	//if the queue Q is not a empty queue, 
	//then return Q's front node's data  
	//and return OK
	//else return ERROR
	
	if(Q->front == Q->rear)
	{
		return ERROR;
	}
	QueuePtr p = Q->front->next;
	*e = p->data;
	Q->front->next = p->next;
	if(Q->rear == p) Q->rear = Q->front;
	free(p);
	
	return OK;
}

Status IsEmpty(const LinkQueue Q)
{
	return Q.front == Q.rear;
}

Status TravelQueue(const LinkQueue Q, QElemType *e, 
		int (*cmp)(QElemType* a, QElemType* b))
{
	//this function is a standard queue-function
	//but we need it in this program
	QueuePtr p = Q.front->next;
	while(p)
	{
		//printf("\t test:%d %d %d\n", p->data.jid, p->data.pid, p->data.state);
		if((*cmp)(&(p->data), e) != 0)
		{
			*e = p->data;
			return OK;
		}
		
		p = p->next;
		
	}
	
	return ERROR;
}

Status DeleteElem(LinkQueue *Q, QElemType *e, \
		int (*cmp)(QElemType* a, QElemType* b))
{
	QueuePtr q = Q->front;
	QueuePtr p = q->next;
	while(p)
	{
		if((*cmp)(&(p->data), e) != 0)
		{
			*e = p->data;
			q->next = p->next;
			if(Q->rear == p)
			{
				Q->rear = q;
			}
			free(p);
			return OK;
		}
		q = p;
		p = p->next;
	}
	return ERROR;
}
